/**
 * GridDistribAlgo class 
 * 
 * 
 * @created 2007-26-17
 * @author csamson
 */

package objects.distribution;

import objects.*;
import kernel.*;
import java.lang.Math;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;


public class GridDistribAlgo extends DistributionAlgo{

    public GridDistribAlgo(){
    }

    /**
     *The grid distribution constructor
     *
     * @param x the upperLeft corner X coordonate of the sensorNetwork
     * @param y the upperLeft corner Y coordonate of the sensorNetwork
     * @param w the sensorNetwork width
     * @param h the sensorNetwork height
     * @param s the number of sensor in the sensorNetwork
     *
     */
    public GridDistribAlgo(double x, double y, double w, double h, int s){
	_ulX = x;
	_ulY = y;
	_width = w;
	_height = h;

	_sensorAmount = s;
    }

    /**
     * @return the algorithm name
     */
    public String getName(){
	return "gridDistribAlgo";
    }

    /**
     * @return the point table used to place the sensors
     */
    public Point2D[] distribute(){
	Point2D[] result = new Point2D[_sensorAmount];
	//The Network Area
	double area = _width * _height;
	//The area that might be covered by a sensor
	double sensorArea = 2 * (area / _sensorAmount);
	//the ratio between the area and the sensorArea
	double ratio = area / sensorArea;
	double sensorWidth = _width / Math.sqrt(ratio);
	double sensorHeight = _height / Math.sqrt(ratio);

	//We realize two grid and cross them to got a good KCover
	int i =0;
	for(double x = _ulX; x < _width+_ulX ;x += sensorWidth){
	    for(double y = _ulY; y < _height+_ulY ;y += sensorHeight){
		result[i] = new Point2D.Double(x,y);
		i++;
	    }
	}

	int j = i;
	for(double x = _width+_ulX; x > _ulX && j < (_sensorAmount);
	    x -= sensorWidth){
	    for(double y = _height+_ulY; y > _ulY && j < (_sensorAmount);
		y -= sensorHeight){
		result[j] = new Point2D.Double(x,y);
		j++;
	    }
	}
	//We place randomly the other sensors
       	Random rand = new Random();
	for(int k= j;k<result.length;k++){
	    double x = _ulX + (rand.nextDouble() * _width);
	    double y = _ulY + (rand.nextDouble() * _height);
	    result[k] = new Point2D.Double(x,y);
	}

	return result;
    }

}
